package com.service.screenReception.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.service.config.utils.DateUtil;
import com.service.config.utils.JsonXMLUtils;
import com.service.config.utils.ModelMapperUtil;
import com.service.config.utils.RedisUtil;
import com.service.screenReception.dto.*;
import com.service.screenReception.service.BigScreenService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program: CloudCampusService
 * @description:
 * @author: rui
 * @create: 2021-04-01 15:25
 **/
@Service("bigScreenService")
public class BigScreenServiceImpl implements BigScreenService {

    @Resource
    RedisUtil redisUtil;
    @Resource
    RedisTemplate redisTemplate;

    /**
     * 设备数量
     *
     * @param user_id
     * @return
     */
    @Override
    public Map queryDeviceCounts(String user_id) {
        List<SiteDto> list = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_siteData")), SiteDto.class);
        if (list.size() > 0) {
            List list1 = new ArrayList();
            AtomicReference<Integer> sumCount = new AtomicReference<>(0);
            list.forEach(siteDto -> {
                Map map = new HashMap();
                map.put("siteId", siteDto.getId());
                map.put("siteName", siteDto.getName());
                map.put("device", siteDto.getDeviceCounts() != null ? siteDto.getDeviceCounts() : 0);
                if (siteDto.getDeviceCounts() != null) {
                    sumCount.updateAndGet(v -> v + siteDto.getDeviceCounts());
                }
                list1.add(map);
            });
            Map map = new HashMap();
            map.put("sumCount", sumCount);
            map.put("deviceCount", list1);
            return map;
        } else {
            return null;
        }

    }

    /**
     * 设备按照类型分
     *
     * @param user_id
     * @return
     */
    @Override
    public List queryDeviceType(String user_id) {
        List<SiteDto> list = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_siteData")), SiteDto.class);
        List<DeviceDto> list1 = new ArrayList<>();
        if (list.size() > 0) {
            list.forEach(siteDto -> {
                if (siteDto.getDevice() != null) {
                    list1.addAll(siteDto.getDevice());
                }
            });
            //根据设备类型、给设备分组
            Map<String, List<DeviceDto>> map = new HashMap<>();
            list1.stream().collect(Collectors.groupingBy(DeviceDto::getDeviceType))
                    .forEach(map::put);
            List deviceTypeList = new ArrayList();
            map.entrySet().forEach(stringEntry -> {
                Map deviceType = new HashMap();
                deviceType.put("type", stringEntry.getKey());
                deviceType.put("count", stringEntry.getValue().size());
                deviceTypeList.add(deviceType);
            });

            return deviceTypeList;
        } else {
            return null;
        }

    }


    /**
     * 查询实时接入人数
     *
     * @param user_id
     * @return
     */
    @Override
    public Map queryOnlineUserCount(String user_id) {
        List<RealTimeDto> list = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_realUser")), RealTimeDto.class);
//        AtomicReference<Integer> sumCount = new AtomicReference<>(0);
//        list.forEach(realTimeFlowDto -> sumCount.updateAndGet(v -> v + realTimeFlowDto.getValue()));
//        Map map = new HashMap();
//        map.put("sumCount", sumCount);
//        map.put("siteDetail", list);


//        List<TerminalUserDto> list = redisUtil.getList1(user_id.concat("_terminal_user"));
//        list = ModelMapperUtil.strictMapList(list, TerminalUserDto.class);
//        list = list.stream().filter(TerminalUser -> TerminalUser.getOnlineStatus().equals("1")).collect(Collectors.toList());
//
//        //根据设备类型、给设备分组
//        Map<String, List<TerminalUserDto>> map = new HashMap<>();
//        list.stream().collect(Collectors.groupingBy(TerminalUserDto::getSiteId))
//                .forEach(map::put);
//
//        List<RealTimeDto> userCount = new ArrayList();
//        map.entrySet().forEach(userList -> {
//            RealTimeDto realTimeDto = new RealTimeDto();
//            realTimeDto.setSiteId(userList.getKey());
//            realTimeDto.setName(userList.getValue().get(0).getSiteName());
//            realTimeDto.setValue(userList.getValue().size());
//            userCount.add(realTimeDto);
//        });
        Map map1 = new HashMap();
        Integer sumCount1 = list.stream().filter(user -> user.getValue() != null).mapToInt(RealTimeDto::getValue).sum();
        map1.put("sumCount", sumCount1);
        map1.put("siteDetail", list);

        return map1;
    }

    /**
     * 查询当日流量
     *
     * @param user_id
     * @return
     */
    @Override
    public Map querySiteTrafficByDay(String user_id) {
        List<RealTimeDto> siteTrafficDtos = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_traffic")), RealTimeDto.class);
        AtomicReference<Integer> sumTraffic = new AtomicReference<>(0);
        siteTrafficDtos.forEach(siteTraffic -> {
            sumTraffic.updateAndGet(v -> v + siteTraffic.getValue());
        });
        Map map1 = new HashMap();
        map1.put("sumTraffic", sumTraffic);
        map1.put("siteTraffic", siteTrafficDtos);
        return map1;
    }

    /**
     * 查询当月流量
     *
     * @param user_id
     * @return
     */
    @Override
    public Map querySiteTrafficByMonth(String user_id) {
        List<RealTimeDto> siteTrafficDtos = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_trafficMonth")), RealTimeDto.class);
        AtomicReference<Integer> sumTraffic = new AtomicReference<>(0);
        siteTrafficDtos.forEach(siteTraffic -> {
            sumTraffic.updateAndGet(v -> v + siteTraffic.getValue());
        });
        Map map1 = new HashMap();
        map1.put("sumTraffic", sumTraffic);
        map1.put("siteTraffic", siteTrafficDtos);
        return map1;
    }

    /**
     * 查询当年流量
     *
     * @param user_id
     * @return
     */
    @Override
    public Map querySiteTrafficByYear(String user_id) {
        List<RealTimeDto> siteTrafficDtos = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_trafficYear")), RealTimeDto.class);
        AtomicReference<Integer> sumTraffic = new AtomicReference<>(0);
        siteTrafficDtos.forEach(siteTraffic -> {
            sumTraffic.updateAndGet(v -> v + siteTraffic.getValue());
        });
        Map map1 = new HashMap();
        map1.put("sumTraffic", sumTraffic);
        map1.put("siteTraffic", siteTrafficDtos);
        return map1;
    }



//    /**
//     * 查询历史流量
//     *
//     * @param user_id
//     * @return
//     */
//    @Override
//    public Map querySiteTrafficByHistory(String user_id) {
//        List<RealTimeDto> siteTrafficDtos = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_trafficHistory")), RealTimeDto.class);
//        AtomicReference<Integer> sumTraffic = new AtomicReference<>(0);
//        siteTrafficDtos.forEach(siteTraffic -> {
//            sumTraffic.updateAndGet(v -> v + siteTraffic.getValue());
//        });
//        Map map1 = new HashMap();
//        map1.put("sumTraffic", sumTraffic);
//        map1.put("siteTraffic", siteTrafficDtos);
//        return map1;
//    }

    /**
     * 查询TopN应用流量  =>没有数据，不知道数据格式
     *
     * @param user_id
     * @return
     */
    @Override
    public List querySsidTraffic(String user_id) {
        List<TopNSsidTrafficDto> list = ModelMapperUtil.strictMapList(redisUtil.getList1(user_id.concat("_TOPN_SSID_TRAFFIC")),TopNSsidTrafficDto.class);
        Map<String,List<TopNSsidTrafficDto>>map = new HashMap<>();
        list.stream().collect(Collectors.groupingBy(TopNSsidTrafficDto::getSiteId))
                .forEach(map::put);
        List finalList = new ArrayList();
        map.entrySet().forEach(ssid->{
            Map map1 = new HashMap();
            map1.put("siteName",ssid.getValue().get(0).getSiteName());
            map1.put("ssids",ssid.getValue());
            finalList.add(map1);
        });
        return finalList;
    }


    /**
     * 终端用户在线时长列表
     *
     * @param userId,sign => onlineTime 代表终端在线时长；traffic 代表终端流量
     * @return
     */
    @Override
    public Map queryTerminalUser(String userId, String sign) throws Exception {
        List<String> list = new ArrayList<>();
        list.addAll(redisUtil.getList1(userId.concat("_online_terminal_user")));
        list.addAll(redisUtil.getList1(userId.concat("_offline_terminal_user")));

        List<TerminalUserDtoString> front = new ArrayList<>();
        List<TerminalUserDtoString> behind = new ArrayList<>();
        List<TerminalUserDtoString> finalList = new ArrayList<>();
        List<TerminalUserDtoString> terminalUserDtoStringArrayList = new ArrayList<>();

        for (Object o : list) {
         //   TerminalUserDtoString terminalUserDtoString1 = JsonXMLUtils.json2obj(o.toString(), TerminalUserDtoString.class);
            String obj2json = JsonXMLUtils.obj2json(o);
            TerminalUserDtoString terminalUserDtoString = JsonXMLUtils.json2obj(obj2json, TerminalUserDtoString.class);
            terminalUserDtoStringArrayList.add(terminalUserDtoString);
        }
       // List<TerminalUserDtoString> terminalUserDtoStrings = ModelMapperUtil.strictMapList(list, TerminalUserDtoString.class);
        List<TerminalUserDtoString> terminalUserDtoStrings = new ArrayList<>();
        if ("onlineTime".equals(sign)) {
            terminalUserDtoStringArrayList.stream().forEach(terminalUserDtoString -> {
                try {
                    if (JsonXMLUtils.obj2json(terminalUserDtoString).contains("onlineTime")){
                        terminalUserDtoStrings.add(terminalUserDtoString);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            terminalUserDtoStrings.forEach(terminalUserDto -> {
                terminalUserDto.setAccessTime(terminalUserDto.getAccessTime().equals("0") ? "0" :DateUtil.timeStamp2Date(terminalUserDto.getAccessTime(), "yyyy-MM-dd HH:mm:ss"));
                //terminalUserDto.setTime(terminalUserDto.getOnlineTime() != 0 ?DateUtil.getDatePoor(terminalUserDto.getOnlineTime()) : "0分");
                terminalUserDto.setTime(DateUtil.getDatePoor(terminalUserDto.getOnlineTime()));

            });
            finalList = terminalUserDtoStrings.stream().sorted((u1, u2) -> u2.getOnlineTime().compareTo(u1.getOnlineTime())).collect(Collectors.toList());

        } else if ("traffic".equals(sign)) {
            finalList = terminalUserDtoStringArrayList.stream().sorted((u1, u2) -> u2.getCumulativeTraffic().compareTo(u1.getCumulativeTraffic())).collect(Collectors.toList());

        }
        if (finalList.size() > 3) {
            front = finalList.subList(0, 3);
            behind = finalList.subList(3, finalList.size());
        } else {
            front = finalList;
        }
        Map map = new HashMap();
        map.put("front", front);
        map.put("behind", behind);

        return map;
    }


    /**
     * 查询设备状态列表
     *
     * @param userId
     * @param
     * @return
     */
    @Override
    public List queryDeviceStatus(String userId) {
        List<SiteDto> list = ModelMapperUtil.strictMapList(redisUtil.getList1(userId.concat("_siteData")), SiteDto.class);
        List<DeviceDto> list1 = new ArrayList<>();
        if (list.size() > 0) {
            list.forEach(siteDto -> {
                if (siteDto.getDevice() != null) {
                    list1.addAll(siteDto.getDevice());
                }
            });

            List<Map> deviceTypeList = new ArrayList();
            for (int i = 0; i < 5; i++) {
                if (i != 2) {
                    Map map = new HashMap();
                    if (i == 0) {
                        map.put("status", "正常");
                    } else if (i == 1) {
                        map.put("status", "告警");
                    } else if (i == 3) {
                        map.put("status", "离线");
                    } else if (i == 4) {
                        map.put("status", "未注册");
                    }
                    map.put("count", 0);
                    deviceTypeList.add(map);
                }
            }

            //根据设备类型、给设备分组
            Map<String, List<DeviceDto>> map = new HashMap<>();
            list1.stream().collect(Collectors.groupingBy(DeviceDto::getStatus))
                    .forEach(map::put);
            map.entrySet().forEach(stringEntry -> {
                deviceTypeList.forEach(device -> {
                    String status = "";
                    if ("正常".equals(device.get("status"))) {
                        status = "0";
                    } else if ("告警".equals(device.get("status"))) {
                        status = "1";
                    } else if ("离线".equals(device.get("status"))) {
                        status = "3";
                    } else if ("未注册".equals(device.get("status"))) {
                        status = "4";
                    }
                    if (status.equals(stringEntry.getKey())) {
                        device.put("count", stringEntry.getValue().size());
                    }
                });
            });
            return deviceTypeList;
        } else {
            return null;
        }
    }


    /**
     * 查询有线无线接入终端数
     *
     * @param userId
     * @param
     * @return
     */
    @Override
    public List queryByAccessType(String userId) {
        List<RealTimeDto> list = new ArrayList<>();
        List<RealTimeDto> list1 = new ArrayList<>();
        list.addAll(redisUtil.getList1(userId.concat("_realUser")));
        list1.addAll(redisUtil.getList1(userId.concat("_offline_realUser")));

        list = ModelMapperUtil.strictMapList(list, RealTimeDto.class);
        list1 = ModelMapperUtil.strictMapList(list1, RealTimeDto.class);
        int sum = list1.stream().filter(user -> user.getValue() != null).mapToInt(RealTimeDto::getValue).sum();
        HashMap map1 = new HashMap();
        map1.put("type", "2");
        map1.put("count", sum);
        int sum1 = list.stream().filter(user -> user.getValue() != null).mapToInt(RealTimeDto::getValue).sum();
        HashMap map = new HashMap();
        map.put("type", "1");
        map.put("count", sum1);
        List list2 = new ArrayList();
        list2.add(map1);
        list2.add(map);
////        //根据设备类型、给设备分组
////        Map<String, List<TerminalUserDto>> map = new HashMap<>();
////        //02 有线离线用户，01 有线在线用户, 12 无线离线用户，11 无线在线用户。
////        //01在线 02离线
////        list.stream().collect(Collectors.groupingBy(item ->item.getOnlineStatus()))
////                .forEach(map::put);
////
//
////        List<HashMap> list1 = new ArrayList();
////        map.entrySet().forEach(type -> {
////            HashMap map1 = new HashMap();
////            map1.put("type", type.getKey());
////            map1.put("count", type.getValue().size());
////            list1.add(map1);
////        });
//
//        if (list1.size() < 2) {
//            List<String> hasTypes = new ArrayList<>();
//            list1.forEach(item -> hasTypes.add(item.get("type").toString()));
//            if (!hasTypes.contains("2")) {
//                HashMap map1 = new HashMap();
//                map1.put("type", "2");
//                map1.put("count", 0);
//                list1.add(map1);
//            }
//            if (!hasTypes.contains("1")) {
//                HashMap map2 = new HashMap();
//                map2.put("type", "1");
//                map2.put("count", 0);
//                list1.add(map2);
//            }
//            if (!hasTypes.contains("12")) {
//                HashMap map3 = new HashMap();
//                map3.put("type", "12");
//                map3.put("count", 0);
//                list1.add(map3);
//            }
//            if (!hasTypes.contains("11")) {
//                HashMap map4 = new HashMap();
//                map4.put("type", "11");
//                map4.put("count", 0);
//                list1.add(map4);
//            }
       // }
        return list2;
    }


    /**
     * 云管理站点设备健康
     * @param userId
     * @param sign
     * @return
     */
    @Override
    public Map queryHealth(String userId,String sign) {
        DecimalFormat df = new DecimalFormat("#.0");

        List<SiteHealthDto> list = ModelMapperUtil.strictMapList(redisUtil.getList1(userId.concat("_SITE_HEALTH")), SiteHealthDto.class);
        List<HealthDto> healthDtos = new ArrayList<>();
        Map map = new HashMap();
        if("deviceHealth".equals(sign)){
            list.forEach(siteHealthDto -> {
                HealthDto healthDto = new HealthDto();
                healthDto.setName(siteHealthDto.getSiteName());
                healthDto.setValue(siteHealthDto.getDeviceHealth());
                healthDtos.add(healthDto);
            });
                map.put("average",df.format(healthDtos.stream().collect(Collectors.averagingInt(HealthDto::getValue))));
        }else if("siteHealth".equals(sign)){
            list.forEach(siteHealthDto -> {
                HealthDto healthDto = new HealthDto();
                healthDto.setName(siteHealthDto.getSiteName());
                healthDto.setValue(siteHealthDto.getSiteHealth());
                healthDtos.add(healthDto);
            });
                map.put("average",df.format(healthDtos.stream().collect(Collectors.averagingInt((HealthDto::getValue)))));

        }else if("radioHealth".equals(sign)){
            list.forEach(siteHealthDto -> {
                HealthDto healthDto = new HealthDto();
                healthDto.setName(siteHealthDto.getSiteName());
                healthDto.setValue(siteHealthDto.getRadioHealth());
                healthDtos.add(healthDto);
            });
                map.put("average",df.format(healthDtos.stream().collect(Collectors.averagingInt(HealthDto::getValue))));

        }else if("deviceHealthPoint".equals(sign)){
            list.forEach(siteHealthDto -> {
                HealthDto healthDto = new HealthDto();
                healthDto.setName(siteHealthDto.getSiteName());
                healthDto.setValue(siteHealthDto.getDeviceHealthPoint()!=null ? siteHealthDto.getDeviceHealthPoint():0);
                healthDtos.add(healthDto);
            });
                map.put("average",df.format(healthDtos.stream().collect(Collectors.averagingInt(HealthDto::getValue))));

        }
        map.put("siteHealth",healthDtos);
        return map;
    }



}
